package com.qcrud.core.parsing;

import com.qcrud.annotation.Column;
import com.qcrud.annotation.Id;
import com.qcrud.annotation.Table;
import com.qcrud.exception.QcrudException;
import com.qcrud.tookit.FieldUtils;
import com.qcrud.tookit.StringUtils;
import lombok.Getter;
import lombok.Setter;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Getter
@Setter
public class TableInfo {
    /**
     * 表名
     */
    private String name;
    /**
     * 主键ID
     */
    private ColumnInfo idInfo;
    /**
     * 字段信息列表
     */
    private List<ColumnInfo> columnInfos;

    public String columnJoining() {
        StringBuffer sql = new StringBuffer();
        sql.append("(");
        sql.append(columnInfos.stream().map(c -> "?").collect(Collectors.joining(",")));
        sql.append(")");
        return sql.toString();
    }

    public static TableInfo parse(Class<?> clazz) {
        List<Field> fields = FieldUtils.getFieldList(clazz);
        if (null == fields || fields.isEmpty()) {
            throw new QcrudException("Class attribute cannot be empty: " + clazz.getName());
        }
        /**
         * 表信息解析
         */
        TableInfo tableInfo = new TableInfo();
        Table table = clazz.getAnnotation(Table.class);
        String tableName = clazz.getSimpleName();
        if (null != table) {
            if (StringUtils.isNotBlank(table.value())) {
                tableName = table.value();
            }
            if (StringUtils.isNotBlank(table.schema())) {
                tableName = table.schema() + "." + tableName;
            }
        } else {
            tableName = StringUtils.camelToUnderline(tableName);
        }
        tableInfo.setName(tableName);
        /**
         * 字段解析
         */
        List<ColumnInfo> columnInfos = new ArrayList<>();
        for (Field field : fields) {
            // 主键字段
            String fieldName = field.getName();
            ColumnInfo idInfo = null;
            Id id = field.getAnnotation(Id.class);
            if (null != id) {
                idInfo = new ColumnInfo();
                idInfo.setProperty(fieldName);
                idInfo.setField(field);
                if (!StringUtils.isBlank(id.value())) {
                    idInfo.setName(id.value());
                    idInfo.setConvert(!id.value().equals(fieldName));
                } else {
                    idInfo.setName(StringUtils.camelToUnderline(fieldName));
                }
            } else if ("id".equals(fieldName)) {
                idInfo = new ColumnInfo(StringUtils.camelToUnderline(fieldName),
                        fieldName, false, field);
            }
            if (null != idInfo) {
                if (null != tableInfo.getIdInfo()) {
                    throw new QcrudException("Only unique primary keys are supported");
                }
                tableInfo.setIdInfo(idInfo);
                continue;
            }
            // 普通字段
            boolean convert = false;
            String columnName = null;
            Column column = field.getAnnotation(Column.class);
            if (null != column) {
                if (column.ignore()) {
                    continue;
                }
                columnName = column.value();
                convert = true;
            }
            if (null == columnName) {
                columnName = StringUtils.camelToUnderline(field.getName());
            }
            columnInfos.add(new ColumnInfo(columnName, field.getName(), convert, field));
        }
        tableInfo.setColumnInfos(columnInfos);
        return tableInfo;
    }
}
